home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 June / PersonalComputerWorld-June2009-CoverdiscCD.iso / Software / Freeware / Firebug 1.3.3 / firebug-1.3.3-fx.xpi / content / firebug / sourceCache.js < prev    next >
Encoding:
JavaScript  |  2009-02-19  |  8.4 KB  |  293 lines

  1. /* See license.txt for terms of usage */
  2.  
  3. FBL.ns(function() { with (FBL) {
  4.  
  5. // ************************************************************************************************
  6. // Constants
  7.  
  8. const Cc = Components.classes;
  9. const Ci = Components.interfaces;
  10. const nsIIOService = Ci.nsIIOService;
  11. const nsIRequest = Ci.nsIRequest;
  12. const nsICachingChannel = Ci.nsICachingChannel;
  13. const nsIScriptableInputStream = Ci.nsIScriptableInputStream;
  14. const nsIUploadChannel = Ci.nsIUploadChannel;
  15. const nsIHttpChannel = Ci.nsIHttpChannel;
  16.  
  17. const IOService = Cc["@mozilla.org/network/io-service;1"];
  18. const ioService = IOService.getService(nsIIOService);
  19. const ScriptableInputStream = Cc["@mozilla.org/scriptableinputstream;1"];
  20. const chromeReg = CCSV("@mozilla.org/chrome/chrome-registry;1", "nsIToolkitChromeRegistry");
  21.  
  22. const LOAD_FROM_CACHE = nsIRequest.LOAD_FROM_CACHE;
  23. const LOAD_BYPASS_LOCAL_CACHE_IF_BUSY = nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
  24.  
  25. const NS_BINDING_ABORTED = 0x804b0002;
  26.  
  27. // ************************************************************************************************
  28.  
  29. Firebug.SourceCache = function(window, context)
  30. {
  31.     this.window = window;
  32.     this.context = context;
  33.     this.cache = {};
  34. };
  35.  
  36. Firebug.SourceCache.prototype =
  37. {
  38.     isCached: function(url)
  39.     {
  40.         return this.cache.hasOwnProperty(url);
  41.     },
  42.     
  43.     loadText: function(url, method, file)
  44.     {
  45.         var lines = this.load(url, method, file);
  46.         return lines ? lines.join("\n") : null;
  47.     },
  48.  
  49.     load: function(url, method, file)
  50.     {
  51.         if ( this.cache.hasOwnProperty(url) )
  52.             return this.cache[url];
  53.  
  54.         var d = FBL.splitDataURL(url);  //TODO the RE should not have baseLine
  55.         if (d)
  56.         {
  57.             var src = d.encodedContent;
  58.             var data = decodeURIComponent(src);
  59.             var lines = data.split(/\r\n|\r|\n/);
  60.             this.cache[url] = lines;
  61.  
  62.             return lines;
  63.         }
  64.  
  65.         var j = FBL.reJavascript.exec(url);
  66.         if (j)
  67.         {
  68.             var src = url.substring(FBL.reJavascript.lastIndex);
  69.             var lines = src.split(/\r\n|\r|\n/);
  70.             this.cache[url] = lines;
  71.  
  72.             return lines;
  73.         }
  74.  
  75.         var c = FBL.reChrome.test(url);
  76.         if (c)
  77.         {
  78.             if (Firebug.filterSystemURLs)
  79.                 return;  // ignore chrome
  80.  
  81.             var chromeURI = ioService.newURI(url, null, null);
  82.             var localURI = chromeReg.convertChromeURL(chromeURI);
  83.             return this.loadFromLocal(localURI.spec);
  84.         } 
  85.          
  86.         c = FBL.reFile.test(url);
  87.         if (c)
  88.         {
  89.             return this.loadFromLocal(url);
  90.         }
  91.  
  92.         // Unfortunately, the URL isn't available so, let's try to use FF cache. 
  93.         // Notice that additional network request to the server can be made in 
  94.         // this method (double-load).
  95.         return this.loadFromCache(url, method, file);
  96.     },
  97.  
  98.     loadFromLocal: function(url)
  99.     {
  100.         // if we get this far then we have either a file: or chrome: url converted to file:
  101.         var src = getResource(url);
  102.         if (src)
  103.         {
  104.             var lines = src.split(/\r\n|\r|\n/);
  105.             this.cache[url] = lines;
  106.  
  107.             return lines;
  108.         }  
  109.     },
  110.     
  111.     loadFromCache: function(url, method, file)
  112.     {
  113.         var doc = this.context.window.document;
  114.         if (doc)
  115.             var charset = doc.characterSet;
  116.         else
  117.             var charset = "UTF-8";
  118.  
  119.         var channel;
  120.         try
  121.         {
  122.             channel = ioService.newChannel(url, null, null);
  123.             channel.loadFlags |= LOAD_FROM_CACHE | LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
  124.  
  125.             if (method && (channel instanceof nsIHttpChannel))
  126.             {
  127.                 var httpChannel = QI(channel, nsIHttpChannel);
  128.                 httpChannel.requestMethod = method;
  129.             }
  130.         }
  131.         catch (exc)
  132.         {
  133.             return;
  134.         }
  135.  
  136.         if (url == this.context.browser.contentWindow.location.href)
  137.         {
  138.             if (channel instanceof nsIUploadChannel)
  139.             {
  140.                 var postData = getPostStream(this.context);
  141.                 if (postData)
  142.                 {
  143.                     var uploadChannel = QI(channel, nsIUploadChannel);
  144.                     uploadChannel.setUploadStream(postData, "", -1);
  145.                 }
  146.             }
  147.  
  148.             if (channel instanceof nsICachingChannel)
  149.             {
  150.                 var cacheChannel = QI(channel, nsICachingChannel);
  151.                 cacheChannel.cacheKey = getCacheKey(this.context);
  152.             }
  153.         }
  154.         else if ((method == "PUT" || method == "POST") && file)
  155.         {
  156.             if (channel instanceof nsIUploadChannel)
  157.             {
  158.                 // In case of PUT and POST, don't forget to use the original body.
  159.                 var postData = getPostText(file, this.context);
  160.                 if (postData)
  161.                 {
  162.                     var postDataStream = getInputStreamFromString(postData);
  163.                     var uploadChannel = QI(channel, nsIUploadChannel);
  164.                     uploadChannel.setUploadStream(postDataStream, "application/x-www-form-urlencoded", -1);
  165.                 }
  166.             }
  167.         }
  168.  
  169.         var stream;
  170.         try
  171.         {
  172.             stream = channel.open();
  173.         }
  174.         catch (exc)
  175.         {
  176.             return ["sourceCache.load FAILS for url="+url, exc.toString()];
  177.         }
  178.  
  179.         try
  180.         {
  181.             var data = readFromStream(stream, charset);
  182.             var lines = data.split(/\r\n|\r|\n/);
  183.             this.cache[url] = lines;
  184.             return lines;
  185.         }
  186.         catch (exc)
  187.         {
  188.             return ["sourceCache.load FAILS for url="+url, exc.toString()];
  189.         }
  190.         finally
  191.         {
  192.             stream.close();
  193.         }
  194.     },
  195.  
  196.     store: function(url, text)
  197.     {
  198.         var lines = splitLines(text);
  199.         return this.storeSplitLines(url, lines);
  200.     },
  201.     
  202.     storeSplitLines: function(url, lines)  
  203.     {
  204.         return this.cache[url] = lines;
  205.     },
  206.  
  207.     invalidate: function(url)
  208.     {
  209.         delete this.cache[url];
  210.     },
  211.  
  212.     getLine: function(url, lineNo)
  213.     {
  214.         var lines = this.load(url);
  215.         if (lines)
  216.         {
  217.             if (lineNo <= lines.length)
  218.                 return lines[lineNo-1];
  219.             else
  220.                 return (lines.length == 1) ? lines[0] : "("+lineNo+" out of range "+lines.length+")";
  221.         }
  222.         else
  223.             return "(no source for "+url+")";
  224.     }
  225. };
  226.  
  227. // xxxHonza getPostText and readPostTextFromRequest are copied from
  228. // net.js. These functions should be removed when this cache is
  229. // refactored due to the double-load problem.
  230. function getPostText(file, context)
  231. {
  232.     if (!file.postText)
  233.         file.postText = readPostTextFromPage(file.href, context);
  234.  
  235.     if (!file.postText)
  236.         file.postText = readPostTextFromRequest(file.request, context);
  237.  
  238.     return file.postText;
  239. }
  240.  
  241. // ************************************************************************************************
  242.  
  243. function getPostStream(context)
  244. {
  245.     try
  246.     {
  247.         var webNav = context.browser.webNavigation;
  248.         var descriptor = QI(webNav, Ci.nsIWebPageDescriptor).currentDescriptor;
  249.         var entry = QI(descriptor, Ci.nsISHEntry);
  250.  
  251.         if (entry.postData)
  252.         {
  253.             // Seek to the beginning, or it will probably start reading at the end
  254.             var postStream = QI(entry.postData, Ci.nsISeekableStream);
  255.             postStream.seek(0, 0);
  256.             return postStream;
  257.         }
  258.      }
  259.      catch (exc)
  260.      {
  261.      }
  262. }
  263.  
  264. function getCacheKey(context)
  265. {
  266.     try
  267.     {
  268.         var webNav = context.browser.webNavigation;
  269.         var descriptor = QI(webNav, Ci.nsIWebPageDescriptor).currentDescriptor;
  270.         var entry = QI(descriptor, Ci.nsISHEntry);
  271.         return entry.cacheKey;
  272.      }
  273.      catch (exc)
  274.      {
  275.      }
  276. }
  277.  
  278. function doublePostForbiddenMessage(url)
  279. {
  280.     var msg = "Firebug needs to POST to the server to get this information for url: "+url+"\n";
  281.     msg += " This second POST can interfere with some sites.\n"
  282.     msg += " If you want to send the POST again, open a new tab in Firefox, use URL 'about:config', ";
  283.     msg += "set boolean value 'extensions.firebug.allowDoublePost' to true\n";
  284.     msg += " This value is reset every time you restart Firefox\n";
  285.     msg += " This problem will disappear when https://bugzilla.mozilla.org/show_bug.cgi?id=430155 is shipped\n";
  286.  
  287.     return msg.split('\n');
  288. }
  289.  
  290. // ************************************************************************************************
  291.  
  292. }});
  293.